home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / comm / dnet20us.2 < prev    next >
Internet Message Format  |  1989-04-29  |  56KB

  1. Path: xanth!nic.MR.NET!indri!lll-winken!ames!oliveb!sun!rishathra!page
  2. From: page%rishathra@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i103:  dnet - networking code (unix side) v2.0, Part02/02
  5. Message-ID: <101943@sun.Eng.Sun.COM>
  6. Date: 29 Apr 89 02:38:19 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2495
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: dillon@postgres.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 89, Issue 103
  13. Archive-name: comm/dnet20-us.2
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    dnet/net.c
  24. #    dnet/internal.c
  25. #    dnet/globals.c
  26. #    dnet/files.c
  27. #    dnet/dnet.h
  28. #    dnet/dnet.c
  29. #    dnet/Makefile
  30. #    dnet/MODS
  31. #    dnet.servers
  32. #    doc/history
  33. #    doc/dnet.doc
  34. #    doc/putfiles.doc
  35. #    doc/dsoc.doc
  36. #    doc/dnetlib.doc
  37. #    doc/draw.doc
  38. #    lib/dnetlib.h
  39. #    lib/dnetlib.c
  40. #    lib/Makefile
  41. #    server/sgcopy.c
  42. #    server/sshell.c
  43. #    server/sloadav.c
  44. #    server/scopy.c
  45. #    server/Makefile
  46. #    server/servers.h
  47. # This is archive 2 of a 2-part kit.
  48. # This archive created: Thu Apr 27 15:41:48 1989
  49. if `test ! -d dnet`
  50. then
  51.   mkdir dnet
  52.   echo "mkdir dnet"
  53. fi
  54. echo "extracting dnet/net.c"
  55. sed 's/^X//' << \SHAR_EOF > dnet/net.c
  56. X
  57. X/*
  58. X *  NET.C
  59. X *
  60. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  61. X *
  62. X *  NetWork raw device interface.  Replace with whatever interface you
  63. X *  want.
  64. X */
  65. X
  66. X#include "dnet.h"
  67. X#include <sys/stat.h>
  68. X
  69. XRcvInt()
  70. X{
  71. X    int n = read(0, RcvBuf + RcvData, RCVBUF - RcvData);
  72. X    if (n >= 0)
  73. X    RcvData += n;
  74. X    if (n <= 0)         /* disallow infinite fast-timeout select loops */
  75. X    RExpect = 0;
  76. X    if (DDebug && n < 0) {
  77. X    write(2, "RcvInt ERR\n", 11);
  78. X    }
  79. X}
  80. X
  81. Xstatic struct sgttyb    ttym;
  82. Xstatic struct stat    Stat;
  83. X
  84. XNetOpen()
  85. X{
  86. X    int async = 1;
  87. X
  88. X    fstat(0, &Stat);
  89. X    fchmod(0, 0600);
  90. X    /*
  91. X    signal(SIGIO, RcvInt);
  92. X    */
  93. X    ioctl (0, TIOCGETP, &ttym);
  94. X    ttym.sg_flags |= RAW;
  95. X    ttym.sg_flags &= ~CBREAK;
  96. X    ttym.sg_flags &= ~ECHO;
  97. X    ioctl (0, TIOCSETP, &ttym);
  98. X    /*
  99. X    ioctl (0, FIOASYNC, &async);
  100. X    */
  101. X    ioctl (0, FIONBIO, &async);
  102. X}
  103. X
  104. XNetClose()
  105. X{
  106. X    int async = 0;
  107. X
  108. X    fchmod(0, Stat.st_mode);
  109. X    ioctl (0, FIONBIO, &async);
  110. X    /*
  111. X    ioctl (0, FIOASYNC, &async);
  112. X    */
  113. X    ioctl (0, TIOCGETP, &ttym);
  114. X    ttym.sg_flags &= ~RAW;
  115. X    ttym.sg_flags |= ECHO;
  116. X    ioctl (0, TIOCSETP, &ttym);
  117. X}
  118. X
  119. XNetWrite(buf, bytes, expectreply)
  120. Xubyte *buf;
  121. X{
  122. X    if (expectreply)
  123. X    DidWrite = 1;
  124. X    if (DDebug)
  125. X    fprintf(stderr, "NETWRITE %08lx %ld\n", buf, bytes);
  126. X    gwrite(0, buf, bytes);
  127. X}
  128. X
  129. Xgwrite(fd, buf, bytes)
  130. Xregister char *buf;
  131. Xregister long bytes;
  132. X{
  133. X    register long n;
  134. X    while (bytes) {
  135. X    n = write(fd, buf, bytes);
  136. X    if (n > 0) {
  137. X        bytes -= n;
  138. X        buf += n;
  139. X        continue;
  140. X    }
  141. X    if (errno == EINTR)
  142. X        continue;
  143. X    if (errno == EWOULDBLOCK) {
  144. X        fd_set fd_wr;
  145. X        fd_set fd_ex;
  146. X        FD_ZERO(&fd_wr);
  147. X        FD_ZERO(&fd_ex);
  148. X        FD_SET(fd, &fd_wr);
  149. X        FD_SET(fd, &fd_ex);
  150. X        select(fd+1, NULL, &fd_wr, &fd_ex, NULL);
  151. X        continue;
  152. X    }
  153. X    if (errno == EPIPE)
  154. X        return;
  155. X    dneterror("gwrite");
  156. X    }
  157. X}
  158. X
  159. SHAR_EOF
  160. echo "extracting dnet/internal.c"
  161. sed 's/^X//' << \SHAR_EOF > dnet/internal.c
  162. X
  163. X/*
  164. X *  INTERNAL.C
  165. X *
  166. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  167. X *
  168. X *    Usually SCMD_OPEN requests attempt to connect() to the UNIX
  169. X *    domain socket of the server.  However, some 'ports' are designated
  170. X *    as internal to DNET.  They reside here.
  171. X *
  172. X *    -IALPHATERM
  173. X */
  174. X
  175. X#include "dnet.h"
  176. X#include "../server/servers.h"
  177. X#include <sys/stat.h>
  178. X#include <sys/wait.h>
  179. X#include <sys/resource.h>
  180. X#include <sys/uio.h>
  181. X#include <strings.h>
  182. X
  183. Xextern char *getenv();
  184. X
  185. Xisinternalport(port)
  186. Xuword port;
  187. X{
  188. X    if (port == PORT_IALPHATERM)
  189. X    return(1);
  190. X    return(0);
  191. X}
  192. X
  193. Xiconnect(ps, port)
  194. Xint *ps;
  195. Xuword port;
  196. X{
  197. X    if (port == PORT_IALPHATERM)
  198. X    return(ialphaterm_connect(ps, port));
  199. X    return(-1);
  200. X}
  201. X
  202. Xialphaterm_connect(pmaster)
  203. Xint *pmaster;
  204. X{
  205. X    struct sgttyb sg;
  206. X    struct tchars tc;
  207. X    struct ltchars ltc;
  208. X#ifdef TIOCGSIZE
  209. X    struct ttysize ts;
  210. X#else
  211. X#ifdef TIOCGWINSZ
  212. X    struct winsize ws;
  213. X#endif
  214. X#endif
  215. X    int lmode;
  216. X    int fdmaster;
  217. X    int fdslave;
  218. X    int pid;
  219. X    char *slavename;
  220. X
  221. X    ioctl(0, TIOCGETP, (char *)&sg);
  222. X    ioctl(0, TIOCGETC, (char *)&tc);
  223. X    ioctl(0, TIOCGLTC, (char *)<c);
  224. X    ioctl(0, TIOCLGET, (char *)&lmode);
  225. X#ifdef TIOCGSIZE
  226. X    ioctl(0, TIOCGSIZE, &ts);
  227. X#else
  228. X#ifdef TIOCGWINSZ
  229. X    ioctl(0, TIOCGWINSZ, &ws);
  230. X#endif
  231. X#endif
  232. X
  233. X    sg.sg_flags &= ~(RAW);
  234. X    sg.sg_flags |= ECHO;
  235. X#ifdef TIOCGSIZE
  236. X    ts.ts_lines = 23;
  237. X    ts.ts_cols = 77;
  238. X#else
  239. X#ifdef TIOCGWINSZ
  240. X    ws.ws_row = 23;
  241. X    ws.ws_col = 77;
  242. X#endif
  243. X#endif
  244. X
  245. X    if (DDebug)
  246. X    fprintf(stderr, "PTY openning internal pty\n");
  247. X    if (openpty(&fdmaster, &fdslave, &slavename) >= 0) {
  248. X    if (DDebug)
  249. X        fprintf(stderr, "PTY open successfull\n");
  250. X    if ((pid = fork()) == NULL) {
  251. X        int i;
  252. X        setenv("DNET=", "IALPHATERM");
  253. X        setuid(getuid());
  254. X        signal(SIGHUP, SIG_DFL);
  255. X        signal(SIGINT, SIG_DFL);
  256. X        signal(SIGQUIT, SIG_DFL);
  257. X        signal(SIGTERM, SIG_DFL);
  258. X        signal(SIGCHLD, SIG_DFL);
  259. X        signal(SIGTSTP, SIG_IGN);
  260. X        ioctl(open("/dev/tty", 2), TIOCNOTTY, NULL);
  261. X        close(open(slavename, 0));
  262. X        dup2(fdslave, 0);
  263. X        dup2(0, 1);
  264. X        dup2(0, 2);
  265. X        for (i = 3; i < 256; ++i)
  266. X        close(i);
  267. X        ioctl(0, TIOCSETN, &sg);
  268. X        ioctl(0, TIOCSETC, &tc);
  269. X        ioctl(0, TIOCSLTC, <c);
  270. X        ioctl(0, TIOCLSET, &lmode);
  271. X#ifdef TIOCSSIZE
  272. X            ioctl(0, TIOCSSIZE, &ts);
  273. X#else
  274. X#ifdef TIOCSWINSZ
  275. X            ioctl(0, TIOCSWINSZ, &ws);
  276. X#endif
  277. X#endif
  278. X        {
  279. X        char *shell = getenv("SHELL");
  280. X        char *home = getenv("HOME");
  281. X        if (!shell)
  282. X            shell = "/bin/sh";
  283. X        if (!home)
  284. X            home = ".";
  285. X        chdir(home);
  286. X        execl(shell, "-fshell", NULL);
  287. X        perror(shell);
  288. X        }
  289. X        _exit(1);
  290. X    }
  291. X    if (pid > 0) {
  292. X        *pmaster = fdmaster;
  293. X        close(fdslave);
  294. X        if (DDebug)
  295. X                fprintf(stderr, "PTY OPEN OK.2\n");
  296. X        return(1);
  297. X    }
  298. X    close(fdmaster);
  299. X    close(fdslave);
  300. X    if (DDebug)
  301. X            fprintf(stderr, "PTY OPEN FAILURE.1\n");
  302. X    }
  303. X    if (DDebug)
  304. X        fprintf(stderr, "PTY OPEN FAILURE.2\n");
  305. X    return(-1);
  306. X}
  307. X
  308. Xopenpty(pfdm, pfds, pnames)
  309. Xint *pfdm;
  310. Xint *pfds;
  311. Xchar **pnames;
  312. X{
  313. X    static char ptcs[] = { "0123456789abcdef" };
  314. X    static char plate[] = { "/dev/ptyxx" };
  315. X    struct stat stat;
  316. X    int i;
  317. X    int j;
  318. X
  319. X    for (i = 'p';; ++i) {
  320. X    plate[8] = i;
  321. X    plate[9] = ptcs[0];
  322. X    if (lstat(plate, &stat) < 0)
  323. X        break;
  324. X    for (j = 0; ptcs[j]; ++j) {
  325. X        plate[9] = ptcs[j];
  326. X        plate[5] = 'p';
  327. X        if ((*pfdm = open(plate, O_RDWR)) >= 0) {
  328. X        plate[5] = 't';
  329. X        if ((*pfds = open(plate, O_RDWR)) >= 0) {
  330. X            *pnames = plate;
  331. X            if (DDebug)
  332. X            fprintf(stderr, "PTY FOUND %s\n", *pnames);
  333. X            return(1);
  334. X        }
  335. X        close(*pfdm);
  336. X        }
  337. X    }
  338. X    }
  339. X    return(-1);
  340. X}
  341. X
  342. Xisetrows(fd, rows)
  343. X{
  344. X#ifdef TIOCSSIZE
  345. X    struct ttysize ts;
  346. X    if (ioctl(fd, TIOCGSIZE, &ts) >= 0) {
  347. X    ts.ts_lines = rows;
  348. X    ioctl(fd, TIOCSSIZE, &ts);
  349. X    }
  350. X#else
  351. X#ifdef TIOCSWINSZ
  352. X    struct winsize ws;
  353. X    if (ioctl(fd, TIOCGWINSZ, &ws) >= 0) {
  354. X    ws.ws_row = rows;
  355. X    ioctl(fd, TIOCSWINSZ, &ws);
  356. X    }
  357. X#endif
  358. X#endif
  359. X}
  360. X
  361. Xisetcols(fd, cols)
  362. X{
  363. X#ifdef TIOCSSIZE
  364. X    struct ttysize ts;
  365. X    if (ioctl(fd, TIOCGSIZE, &ts) >= 0) {
  366. X    ts.ts_cols = cols;
  367. X    ioctl(fd, TIOCSSIZE, &ts);
  368. X    }
  369. X#else
  370. X#ifdef TIOCSWINSZ
  371. X    struct winsize ws;
  372. X    if (ioctl(fd, TIOCSWINSZ, &ws) >= 0) {
  373. X    ws.ws_col = cols;
  374. X    ioctl(fd, TIOCSWINSZ, &ws);
  375. X    }
  376. X#endif
  377. X#endif
  378. X}
  379. X
  380. SHAR_EOF
  381. echo "extracting dnet/globals.c"
  382. sed 's/^X//' << \SHAR_EOF > dnet/globals.c
  383. X
  384. X/*
  385. X *  GLOBALS.C
  386. X *
  387. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  388. X */
  389. X
  390. X#include "dnet.h"
  391. X
  392. Xint Enable_Abort;
  393. X
  394. Xlong USecPerByte = 1000;/*  for 9600 baud.. should really set properly */
  395. Xint DNet_fd = -1;    /*  Master listen socket    */
  396. XPKT Pkts[9];        /*  data buffers for packets    */
  397. XPKT *Raux = Pkts+8;    /*  next packet in        */
  398. Xubyte WCBuf[64];
  399. XPKT *RPak[4] = { Pkts+0,Pkts+1,Pkts+2,Pkts+3 };
  400. XPKT *WPak[4] = { Pkts+4,Pkts+5,Pkts+6,Pkts+7 };
  401. XCHAN Chan[MAXCHAN];    /*  Channels               */
  402. XLIST TxList;           /*  For pending SCMD_DATA reqs.     */
  403. Xfd_set Fdread;
  404. Xfd_set Fdwrite;
  405. Xfd_set Fdexcept;
  406. Xvoid (*Fdstate[FD_SETSIZE])();
  407. Xubyte Fdperm[FD_SETSIZE];
  408. Xuword FdChan[FD_SETSIZE];
  409. Xubyte RcvBuf[RCVBUF];
  410. Xuword RcvData;
  411. Xuword RExpect;
  412. Xubyte RTimedout;
  413. Xubyte WTimedout;
  414. Xuword WChan;        /*  Read and Write channels        */
  415. Xuword RChan;
  416. Xuword RPStart;
  417. Xuword WPStart;
  418. Xuword WPUsed;
  419. Xuword RState;
  420. Xuword Rto_act, Wto_act;
  421. Xubyte DDebug;
  422. Xubyte DidWrite;
  423. Xubyte Restart;
  424. Xubyte DeldQuit;
  425. Xulong NumCon;
  426. X
  427. X
  428. SHAR_EOF
  429. echo "extracting dnet/files.c"
  430. sed 's/^X//' << \SHAR_EOF > dnet/files.c
  431. X
  432. X/*
  433. X * FILES.C
  434. X *
  435. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  436. X *
  437. X *    handles actions on a per file descriptor basis, including accepting
  438. X *    new connections, closing old connections, and transfering data
  439. X *    between connections.
  440. X */
  441. X
  442. X#include "dnet.h"
  443. X
  444. Xextern void do_localopen(), do_connect(), do_open1(), do_openwait(), do_open();
  445. X
  446. X/*
  447. X *  new connection over master port... open request.  read two byte port
  448. X *  number, allocate a channel, and send off to the remote
  449. X */
  450. X
  451. Xvoid
  452. Xdo_localopen(n, fd)
  453. X{
  454. X    struct sockaddr sa;
  455. X    int addrlen = sizeof(sa);
  456. X    int s;
  457. X    uword chan;
  458. X
  459. X    if (DDebug)
  460. X    fprintf(stderr, "DO_LOCALOPEN %ld %ld\n", n, fd);
  461. X    while ((s = accept(fd, &sa, &addrlen)) >= 0) {
  462. X    chan = alloc_channel();
  463. X    fcntl(s, F_SETFL, FNDELAY);
  464. X    if (DDebug)
  465. X        fprintf(stderr, " ACCEPT: %ld on channel %ld ", s, chan);
  466. X    if (chan == 0xFFFF) {
  467. X        ubyte error = 1;
  468. X        gwrite(s, &error, 1);
  469. X        close(s);
  470. X        if (DDebug)
  471. X            fprintf(stderr, "(no channels)\n");
  472. X        continue;
  473. X    } 
  474. X    Fdstate[s] = do_open1;
  475. X    FdChan[s] = chan;
  476. X    FD_SET(s, &Fdread);
  477. X    FD_SET(s, &Fdexcept);
  478. X    Chan[chan].fd = s;
  479. X    Chan[chan].state = CHAN_LOPEN;
  480. X    if (DDebug)
  481. X        fprintf(stderr, "(State = CHAN_LOPEN)\n");
  482. X    }
  483. X}
  484. X
  485. Xvoid
  486. Xdo_open1(n, fd)
  487. X{
  488. X    uword port;
  489. X    char  trxpri[2];
  490. X    uword chan = FdChan[fd];
  491. X    COPEN co;
  492. X    int n;
  493. X
  494. X    if (DDebug)
  495. X    fprintf(stderr, "DO_OPEN %ld %ld on channel %ld  ", n, fd, chan);
  496. X    for (;;) {
  497. X        n = read(fd, &port, 2);
  498. X    if (n < 0) {
  499. X        if (errno == EINTR)
  500. X        continue;
  501. X        if (errno == EWOULDBLOCK)
  502. X        return;
  503. X    }
  504. X    read(fd, trxpri, 2);
  505. X    if (n != 2)
  506. X        dneterror("do_open1: unable to read 2 bytes");
  507. X    break;
  508. X    }
  509. X    if (DDebug)
  510. X    fprintf(stderr, "Port %ld\n", port);
  511. X    co.chanh = chan >> 8;
  512. X    co.chanl = chan;
  513. X    co.porth = port >> 8;
  514. X    co.portl = port;
  515. X    co.error = 0;
  516. X    co.pri   = trxpri[1];
  517. X    Chan[chan].port = port;
  518. X    Chan[chan].pri = 126;
  519. X    WriteStream(SCMD_OPEN, &co, sizeof(co), chan);
  520. X    Chan[chan].pri = trxpri[0];
  521. X    Fdstate[fd] = do_openwait;
  522. X    if (DDebug)
  523. X        fprintf(stderr, " Newstate = openwait\n");
  524. X}
  525. X
  526. Xvoid
  527. Xdo_openwait(n, fd)
  528. X{
  529. X    ubyte buf[32];
  530. X    if (DDebug)
  531. X    fprintf(stderr, "************ ERROR DO_OPENWAIT %ld %ld\n", n, fd);
  532. X    n = read(fd, buf, 32);
  533. X    if (DDebug) {
  534. X    fprintf(stderr, "    OPENWAIT, READ %ld bytes\n", n);
  535. X        if (n < 0)
  536. X        perror("openwait:read");
  537. X    }
  538. X}
  539. X
  540. Xvoid
  541. Xdo_open(nn, fd)
  542. X{
  543. X    extern void nop();
  544. X    char buf[256];
  545. X    uword chan = FdChan[fd];
  546. X    int n;
  547. X
  548. X    n = read(fd, buf, sizeof(buf));
  549. X    if (DDebug) {
  550. X    fprintf(stderr, "DO_OPEN %ld %ld, RECEIVE DATA on chan %ld (%ld by)\n",
  551. X        nn, fd, chan, n);
  552. X    fprintf(stderr, " fd, chanfd %ld %ld\n", fd, Chan[chan].fd);
  553. X    if (n < 0)
  554. X        perror("open:read");
  555. X    }
  556. X    if (n == 0 || nn == 2) {    /* application closed / exception cond */
  557. X    CCLOSE cc;
  558. X
  559. X    if (DDebug)
  560. X        fprintf(stderr, " DO_OPEN: REMOTE EOF, channel %d\n", chan);
  561. X
  562. X    cc.chanh = chan >> 8;
  563. X    cc.chanl = chan;
  564. X    WriteStream(SCMD_CLOSE, &cc, sizeof(CCLOSE), chan);
  565. X    Chan[chan].state = CHAN_CLOSE;
  566. X    Chan[chan].flags |= CHANF_LCLOSE;
  567. X    if (Chan[chan].flags & CHANF_RCLOSE) {
  568. X        ;
  569. X        /* should never happen
  570. X        int fd = Chan[chan].fd;
  571. X        Chan[chan].state = CHAN_FREE;
  572. X        Chan[chan].fd = -1;
  573. X        Fdstate[fd] = nop;
  574. X        FD_CLR(fd, &Fdread);
  575. X        FD_CLR(fd, &Fdexcept);
  576. X        close(fd);
  577. X        */
  578. X    } else {
  579. X        FD_CLR(fd, &Fdread);
  580. X        FD_CLR(fd, &Fdexcept);
  581. X    }
  582. X    }
  583. X    if (n > 0) {
  584. X    WriteStream(SCMD_DATA, buf, n, chan);
  585. X    }
  586. X}
  587. X
  588. SHAR_EOF
  589. echo "extracting dnet/dnet.h"
  590. sed 's/^X//' << \SHAR_EOF > dnet/dnet.h
  591. X
  592. X/*
  593. X *  DNET.H
  594. X *
  595. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  596. X */
  597. X
  598. X#include <sys/types.h>
  599. X#include <sys/ioctl.h>
  600. X#include <sys/socket.h>
  601. X#include <sys/time.h>
  602. X#include <sys/file.h>
  603. X
  604. X/* V2.01 */
  605. X#include <sys/param.h>
  606. X#include <pwd.h>
  607. X
  608. X#include <signal.h>
  609. X#include <stdio.h>
  610. X#include <errno.h>
  611. X#ifndef FD_SETSIZE
  612. X#define FD_SETSIZE (sizeof(struct fd_set) * 8)
  613. X#endif
  614. X#ifndef NFDBITS
  615. X#define NFDBITS 32
  616. X#define    FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  617. X#define    FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  618. X#define    FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  619. X#define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  620. X#endif
  621. X#ifndef sigmask
  622. X#define sigmask(m) (1 << ((m)-1))
  623. X#endif
  624. X
  625. X#ifndef LASTTRYDNETSERVERS
  626. X#define LASTTRYDNETSERVERS "/usr/local/lib/dnet/dnet.servers"
  627. X#endif
  628. X
  629. Xstruct Node {
  630. X    struct Node *ln_Succ;
  631. X    struct Node *ln_Pred;
  632. X};
  633. X
  634. Xstruct List {
  635. X    struct Node *lh_Head;
  636. X    struct Node *lh_Tail;
  637. X    struct Node *lh_TailPred;
  638. X};
  639. X
  640. X
  641. Xtypedef unsigned char    ubyte;
  642. Xtypedef unsigned short    uword;
  643. Xtypedef unsigned long    ulong;
  644. X
  645. Xtypedef struct List        LIST;
  646. Xtypedef struct Node        NODE;
  647. X
  648. X#include "channel.h"
  649. X
  650. X#define PKT struct _PKT
  651. X#define XIOR struct _XIOR
  652. X
  653. X#define EMPTY    0    /*  empty (sent)                    */
  654. X#define READY    1    /*  data ready (not sent yet)       */
  655. X#define RCVBUF  4096
  656. X
  657. X#define MAXCHAN 128    /*  Max # of channels supported     */
  658. X#define SYNC    0xFF    /*  SYNC character            */
  659. X#define WTIME    2000000 /*  in micro seconds (expect ack)   */
  660. X#define RTIME    1000000 /*  in micro seconds (read to)      */
  661. X#define MAXPKT    200    /*  maximum packet size  (data area)              */
  662. X#define MINPKT  32    /*  minimum packet size  (data area) for purposes */
  663. X            /*  of determining the dynamic maximum packet size*/
  664. X            /*  only.  Actual minimum is, of course, 1 byte   */
  665. X
  666. X#define OVERHEAD    7    /*  for packets with data        */
  667. X
  668. XXIOR {
  669. X    NODE    io_Node;
  670. X    ubyte   *io_Data;
  671. X    ulong   io_Length;
  672. X    ulong   io_Actual;
  673. X    uword   io_Channel;
  674. X    ubyte   io_Command;
  675. X    ubyte   io_Error;
  676. X    char    io_Pri;
  677. X};
  678. X
  679. XPKT {
  680. X    uword   iolength;    /*  send: length of packet, recv: length of data    */
  681. X    ubyte   state;    /*  EMPTY, READY                    */
  682. X
  683. X    ubyte   sync;    /*  THE PACKET        */
  684. X    ubyte   ctl;
  685. X    ubyte   cchk;
  686. X    ubyte   lenh;
  687. X    ubyte   lenl;
  688. X    ubyte   data[MAXPKT+2];
  689. X};
  690. X
  691. X    /*
  692. X     *    In receiving a packet the receiver can be in one of these
  693. X     *    states.
  694. X     */
  695. X
  696. X#define RS_SYNC 0        /*    Waiting for sync        */
  697. X#define RS_CTL    1        /*    Waiting for command        */
  698. X#define RS_CCHK 2        /*    Waiting for check byte        */
  699. X#define RS_LEN1 3        /*    Waiting for MSB length byte    */
  700. X#define RS_LEN2 4        /*    Waiting for LSB length byte    */
  701. X#define RS_DATA 5        /*    Waiting for data & checksum    */
  702. X
  703. X    /*
  704. X     *    The low level protocol generates packets.   This is used 
  705. X     *    for error checking, data sequencing, retries, restart, etc...
  706. X     *    The packet format is:
  707. X     *
  708. X     *    SYNC sss0xccc CHK
  709. X     *    SYNC sss1xccc CHK nnnnnnnn nnnnnnnn [DATA] CHK2
  710. X     *                msb       lsb
  711. X     *
  712. X     *    sss = sequence #
  713. X     *    B4  = packet contains data
  714. X     *    B3  = reserved (may be used to extend the command set)
  715. X     *    ccc = PKF_?????
  716. X     *
  717. X     *    NOTE that the data length nnn..nn is not checked with either
  718. X     *    CHK or CHK2 .  The protocol will determine if the length
  719. X     *    is reasonable (< MAXPKT) and then try to read that many
  720. X     *    bytes.  The CHK will obviously fail if the length was 
  721. X     *    incorrect.
  722. X     */
  723. X
  724. X#define PKF_SEQUENCE    0xE0    /*  Sequence #            */
  725. X#define PKF_DATA    0x10    /*  1-65535 bytes        */
  726. X#define PKF_RESERVED    0x08    /*  reserved bit        */
  727. X#define PKF_MASK    0x07    /*  command mask        */
  728. X
  729. X#define PKCMD_WRITE    1    /*  A DATA packet        */
  730. X#define PKCMD_CHECK    2    /*  Request ACK or NAK for win    */
  731. X#define PKCMD_ACK    3    /*  ACK a window        */
  732. X#define PKCMD_NAK    4    /*  NAK a window        */
  733. X#define PKCMD_RESTART     5    /*  RESTART dnet.  (new)    */
  734. X#define PKCMD_ACKRSTART    6    /*  ACK a restart  (new)    */
  735. X#define PKCMD_RESERVE3    7
  736. X
  737. X    /*
  738. X     *  All channel multiplexing, channel commands, etc... is encoded
  739. X     *  within a PKCMD_WRITE packet.
  740. X     *
  741. X     *  Channel commands are characterized by a one byte control
  742. X     *  field and up to 7 bytes of data.  The control field format
  743. X     *  is:        10cccnnn [DATA]        ccc = SCMD_??
  744. X     *                    nnn = # additional data bytes
  745. X     */
  746. X
  747. X#define SCMD_SWITCH    0x00    /*  switch active channel #    */
  748. X#define SCMD_OPEN    0x01    /*  open a channel        */
  749. X#define SCMD_CLOSE    0x02    /*  close a channel        */
  750. X#define SCMD_ACKCMD    0x03    /*  ack an open/close request    */
  751. X#define SCMD_EOFCMD    0x04    /*  Reof or Weof        */
  752. X#define SCMD_QUIT    0x05    /*  QUIT dnet            */
  753. X#define SCMD_IOCTL    0x06    /*  channel ioctl (new),PTY sup    */
  754. X#define SCMD_RESERVE1    0x07
  755. X
  756. X    /*
  757. X     *  Stream data is characterized by the following format:
  758. X     *
  759. X     *           msb      lsb    
  760. X     *        11nnnnnn nnnnnnnn [128-16383 bytes DATA]
  761. X     *             0nnnnnnn [0-127 bytes DATA]
  762. X     *
  763. X     *  NOTE:  11000000 0ccccccc nnnnnnnn   reserved for furture ext. of
  764. X     *                    SCMD commands.
  765. X     */
  766. X
  767. X#define SCMD_DATA    0x08    /*  stream command, DATA (dummy ID)    */
  768. X
  769. X    /*
  770. X     *  Each channel can be in one of several states.
  771. X     */
  772. X
  773. X#define CHAN_FREE    0x01    /*  free channel        */
  774. X#define CHAN_ROPEN    0x02    /*  remote open, wait port msg    */
  775. X#define CHAN_LOPEN    0x03    /*  local open, wait reply    */
  776. X#define CHAN_OPEN    0x04    /*  channel open        */
  777. X#define CHAN_CLOSE    0x05    /*  one side of channel closed  */
  778. X
  779. X#define CHANF_ROK    0x01    /*  remote hasn't EOF'd us yet  */
  780. X#define CHANF_WOK    0x02    /*  remote will accept data    */
  781. X#define CHANF_LCLOSE    0x04     /*  channel closed on our side  */
  782. X#define CHANF_RCLOSE    0x08    /*  channel closed on rem side  */
  783. X
  784. Xextern ubyte *RemHead();
  785. Xextern ubyte *malloc();
  786. Xextern char *getenv();
  787. X
  788. X#ifndef NOEXT
  789. Xextern long USecPerByte;
  790. Xextern int DNet_fd;
  791. Xextern PKT Pkts[9];
  792. Xextern ubyte WCBuf[64];
  793. Xextern PKT *RPak[4];
  794. Xextern PKT *WPak[4];
  795. Xextern CHAN Chan[MAXCHAN];
  796. Xextern LIST TxList;           /*  For pending DNCMD_WRITE reqs.   */
  797. Xextern fd_set Fdread;
  798. Xextern fd_set Fdwrite;
  799. Xextern fd_set Fdexcept;
  800. Xextern void (*Fdstate[FD_SETSIZE])();
  801. Xextern ubyte Fdperm[FD_SETSIZE];
  802. Xextern uword FdChan[FD_SETSIZE];
  803. Xextern ubyte RcvBuf[RCVBUF];
  804. Xextern ubyte RTimedout, WTimedout;
  805. Xextern uword Rto_act, Wto_act;
  806. Xextern uword RcvData;
  807. Xextern uword RExpect;
  808. Xextern uword RChan;
  809. Xextern uword WChan;
  810. Xextern uword RPStart;
  811. Xextern uword WPStart;
  812. Xextern uword WPUsed;
  813. Xextern uword RState;
  814. Xextern ubyte DDebug;
  815. Xextern ubyte DidWrite;
  816. Xextern ubyte Restart;
  817. Xextern ubyte DeldQuit;
  818. Xextern ulong NumCon; 
  819. X
  820. Xextern int errno;
  821. X
  822. X#endif
  823. X
  824. SHAR_EOF
  825. echo "extracting dnet/dnet.c"
  826. sed 's/^X//' << \SHAR_EOF > dnet/dnet.c
  827. X
  828. X/*
  829. X *  DNET.C
  830. X *
  831. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  832. X *
  833. X *    Handles action on all active file descriptors and dispatches
  834. X *    to the proper function in FILES.C
  835. X *
  836. X */
  837. X
  838. X#include "dnet.h"
  839. X#include <sys/wait.h>
  840. X#include <sys/resource.h>
  841. X
  842. Xhandle_child()
  843. X{
  844. X    union wait stat;
  845. X    struct rusage rus;
  846. X    while (wait3(&stat, WNOHANG, &rus) > 0);
  847. X}
  848. X
  849. Xchar *
  850. Xshowselect(ptr)
  851. Xfd_set *ptr;
  852. X{
  853. X    static char buf[FD_SETSIZE+32];
  854. X    short i;
  855. X
  856. X    for (i = 0; i < FD_SETSIZE; ++i) {
  857. X    buf[i] = (FD_ISSET(i, ptr)) ? '1' : '0';
  858. X    }
  859. X    buf[i] = 0;
  860. X    return(buf);
  861. X}
  862. X
  863. X
  864. Xloganddie()
  865. X{
  866. X    fflush(stderr);
  867. X    fprintf(stderr, "\nHUPSIGNAL\n");
  868. X    perror("HUP, last error:");
  869. X    fprintf(stderr, "Last select return:\n");
  870. X    fprintf(stderr, "  %s\n", showselect(&Fdread));
  871. X    fprintf(stderr, "  %s\n", showselect(&Fdwrite));
  872. X    fprintf(stderr, "  %s\n", showselect(&Fdexcept));
  873. X    fprintf(stderr, "RcvData = %ld\n", RcvData);
  874. X    fprintf(stderr, "RChan/WChan = %ld/%ld\n", RChan, WChan);
  875. X    fprintf(stderr, "RPStart = %ld\n", RPStart);
  876. X    fprintf(stderr, "WPStart = %ld\n", WPStart);
  877. X    fprintf(stderr, "WPUsed = %ld\n", WPUsed);
  878. X    fprintf(stderr, "RState = %ld\n", RState);
  879. X    fflush(stderr);
  880. X    kill(0, SIGILL);
  881. X    exit(1);
  882. X}
  883. X
  884. X#define SASIZE(sa)      (sizeof(sa)-sizeof((sa).sa_data)+strlen((sa).sa_data))
  885. X
  886. Xmain(ac,av)
  887. Xchar *av[];
  888. X{
  889. X    long sink_mask, dnet_mask;
  890. X    long mark = 0;
  891. X    ubyte notdone;
  892. X    char local_dir[MAXPATHLEN];
  893. X    struct passwd pw_info;
  894. X    extern void RcvInt();
  895. X
  896. X    if (getenv("DNETDIR")) {
  897. X    strcpy(local_dir, getenv("DNETDIR"));
  898. X    if (chdir(local_dir)) {
  899. X        fprintf(stderr, "Unable to chdir to DNETDIR: %s\n", local_dir);
  900. X        exit(1);
  901. X    }
  902. X    freopen("DNET.LOG", "w", stderr);
  903. X    } else {
  904. X    pw_info = *getpwuid(getuid());
  905. X    strcpy(local_dir, pw_info.pw_dir);
  906. X    strcat(local_dir, "/.dnet");
  907. X    if (chdir(local_dir)) {
  908. X        mkdir(local_dir, 0700);
  909. X        if (chdir(local_dir)) {
  910. X        fprintf(stderr, "Unable to create dir %s\n", local_dir);
  911. X        exit(1);
  912. X        }
  913. X    }
  914. X    freopen("DNET.LOG", "w", stderr);
  915. X    }
  916. X    fprintf(stderr, "DNet startup\n");
  917. X    fprintf(stderr, "Log file placed in %s\n", local_dir);
  918. X    fflush(stderr);
  919. X
  920. X    signal(SIGINT, SIG_IGN);
  921. X    signal(SIGPIPE, SIG_IGN);
  922. X    signal(SIGQUIT, SIG_IGN);
  923. X    signal(SIGCHLD, handle_child);
  924. X    signal(SIGHUP, loganddie);
  925. X
  926. X    bzero(Pkts,sizeof(Pkts));
  927. X    setlistenport("");
  928. X
  929. X    {
  930. X    register short i;
  931. X    for (i = 1; i < ac; ++i) {
  932. X        register char *ptr = av[i];
  933. X        if (*ptr != '-') {
  934. X        DDebug = 1;
  935. X        fprintf(stderr, "Debug mode on\n");
  936. X        continue;
  937. X        }
  938. X        switch(*ptr) {
  939. X        case 'B':
  940. X        USecPerByte = atoi(ptr+1) / 10;     /*  bytes per second */
  941. X        USecPerByte = 1000000 / USecPerByte;
  942. X        fprintf(stderr, "Assuming about %ld uS/byte for timeout calc\n",
  943. X            USecPerByte
  944. X        );
  945. X        break;
  946. X        default:
  947. X        fprintf(stderr, "Unknown option: %c\n", *ptr);
  948. X        printf("Unknown option: %c\n", *ptr);
  949. X        exit(1);
  950. X        }
  951. X    }
  952. X    }
  953. X
  954. X    NewList(&TxList);
  955. X
  956. X    Fdperm[0] = 1;
  957. X    Fdstate[0] = RcvInt;
  958. X    FD_SET(0, &Fdread);
  959. X    FD_SET(0, &Fdexcept);
  960. X
  961. X    fprintf(stderr, "DNET RUNNING, Listenfd=%ld\n", DNet_fd);
  962. X    NetOpen();          /* initialize network and interrupt driven read */
  963. X    TimerOpen();        /* initialize timers                            */
  964. X
  965. X    do_netreset();
  966. X    do_restart();
  967. X
  968. X    notdone = 1;
  969. X    while (notdone) {
  970. X    /*
  971. X     *    MAIN LOOP.  select() on all the file descriptors.  Set the
  972. X     *    timeout to infinity (NULL) normally.  However, if there is
  973. X     *    a pending read or write timeout, set the select timeout
  974. X     *    to 2 seconds in case they timeout before we call select().
  975. X     *    (i.e. a timing window).  OR, if we are in the middle of a
  976. X     *    read, don't use descriptor 0 and timeout according to
  977. X     *    the expected read length, then set the descriptor as ready.
  978. X     */
  979. X
  980. X    fd_set fd_rd;
  981. X    fd_set fd_wr;
  982. X    fd_set fd_ex;
  983. X    struct timeval tv, *ptv;
  984. X    int err;
  985. X
  986. X    fd_rd = Fdread;
  987. X    fd_wr = Fdwrite;
  988. X    fd_ex = Fdexcept;
  989. X
  990. X    tv.tv_sec = 0;        /* normally wait forever for an event */
  991. X    tv.tv_usec= 0;
  992. X    ptv = NULL;
  993. X    if ((Rto_act || Wto_act)) {     /* unless timeout pending */
  994. X        ptv = &tv;
  995. X        tv.tv_sec = 2;
  996. X    }
  997. X
  998. X    /*   ... or expecting data (don't just wait for one byte).
  999. X     *
  1000. X     *   This is an attempt to reduce the CPU usage for the process.
  1001. X     *   If we are expecting data over the serial line, then don't
  1002. X     *   return from the select() even if data is available, but
  1003. X     *   wait for the timeout period indicated before reading the
  1004. X     *   data.  Don't wait more than 64 byte times or we may loose
  1005. X     *   some data (the silo's are only so big.. like 128 bytes).
  1006. X     *
  1007. X     *   Currently, USecPerByte is not set properly (set for 9600 baud)
  1008. X     */
  1009. X
  1010. X    if (RExpect) {
  1011. X        ptv = &tv;
  1012. X        tv.tv_usec= USecPerByte * ((RExpect < 64) ? RExpect : 64);
  1013. X        tv.tv_sec = 0;
  1014. X        FD_CLR(0, &fd_rd);
  1015. X    }
  1016. X    err = select(FD_SETSIZE, &fd_rd, &fd_wr, &fd_ex, ptv);
  1017. X    if (RExpect) {
  1018. X        FD_SET(0, &fd_rd);   /* pretend data ready */
  1019. X    }
  1020. X    if (DDebug)
  1021. X        fprintf(stderr, "SERR %ld %ld %08lx %08lx\n",
  1022. X        err, errno, RExpect, ptv
  1023. X        );
  1024. X
  1025. X    if (RTimedout) {
  1026. X        RTimedout = 0;
  1027. X        do_rto();
  1028. X        mark = 0;
  1029. X    }
  1030. X    if (WTimedout) {
  1031. X        WTimedout = 0;
  1032. X        do_wto();
  1033. X    }
  1034. X    if (err < 0) {
  1035. X        if (errno == EBADF) {
  1036. X        perror("select");
  1037. X        dneterror(NULL);
  1038. X        }
  1039. X    } else {
  1040. X        register short i;
  1041. X        register short j;
  1042. X        register long mask;
  1043. X
  1044. X        for (i = 0; i < FD_SETSIZE/NFDBITS; ++i) {
  1045. X        if (mask = fd_ex.fds_bits[i]) {
  1046. X            for (j = i * NFDBITS; mask; (mask >>= 1),(++j)) {
  1047. X            if (mask & 1)
  1048. X                (*Fdstate[j])(2,j);
  1049. X            }
  1050. X        }
  1051. X        if (mask = fd_wr.fds_bits[i]) {
  1052. X            for (j = i * NFDBITS; mask; (mask >>= 1),(++j)) {
  1053. X            if (mask & 1)
  1054. X                (*Fdstate[j])(1,j);
  1055. X            }
  1056. X        }
  1057. X        if (mask = fd_rd.fds_bits[i]) {
  1058. X            for (j = i * NFDBITS; mask; (mask >>= 1),(++j)) {
  1059. X            if (mask & 1)
  1060. X                (*Fdstate[j])(0,j);
  1061. X            }
  1062. X        }
  1063. X        }
  1064. X    }
  1065. X    if (RcvData != mark)
  1066. X        mark = do_rnet();
  1067. X    do_wupdate();
  1068. X    do_wnet();
  1069. X    }
  1070. X    dneterror(NULL);
  1071. X}
  1072. X
  1073. Xvoid
  1074. Xnop()
  1075. X{
  1076. X}
  1077. X
  1078. Xdo_netreset()
  1079. X{
  1080. X    register short i;
  1081. X    register CHAN *ch;
  1082. X    for (i = 0; i < FD_SETSIZE; ++i) {
  1083. X    if (!Fdperm[i])
  1084. X        Fdstate[i] = nop;
  1085. X    }
  1086. X    for (i = 0, ch = Chan; i < MAXCHAN; ++i, ++ch) {
  1087. X    switch(ch->state) {
  1088. X    case CHAN_OPEN:
  1089. X    case CHAN_LOPEN:    /*  pending on network        */
  1090. X    case CHAN_CLOSE:
  1091. X        if (ch->fd >= 0) {
  1092. X        FD_CLR(ch->fd, &Fdread);
  1093. X        FD_CLR(ch->fd, &Fdexcept);
  1094. X        Fdstate[ch->fd] = nop;
  1095. X        close(ch->fd);
  1096. X        ch->fd = -1;
  1097. X        ch->state = CHAN_FREE;
  1098. X        ch->flags = 0;
  1099. X        --NumCon;
  1100. X        }
  1101. X        ClearChan(&TxList, i, 1);
  1102. X        break;
  1103. X    }
  1104. X    }
  1105. X    RPStart = 0;
  1106. X    WPStart = 0;
  1107. X    WPUsed  = 0;
  1108. X    RState  = 0;
  1109. X    RChan = 0;
  1110. X    WChan = 0;
  1111. X}
  1112. X
  1113. Xdo_restart()
  1114. X{
  1115. X    static ubyte buf[3] = { SYNC, PKCMD_RESTART, (SYNC<<1)^PKCMD_RESTART };
  1116. X    Restart = 1;
  1117. X    NetWrite(buf, sizeof(buf), 1);
  1118. X    WTimeout(WTIME);
  1119. X}
  1120. X
  1121. Xsetlistenport(remotehost)
  1122. Xchar *remotehost;
  1123. X{
  1124. X    static struct sockaddr sa[2];
  1125. X    int s;
  1126. X    extern void do_localopen();
  1127. X
  1128. X    if (DNet_fd >= 0) {
  1129. X    unlink(sa[0].sa_data);
  1130. X    Fdstate[DNet_fd] = nop;
  1131. X    Fdperm[DNet_fd] = 0;
  1132. X    FD_CLR(DNet_fd, &Fdread);
  1133. X    FD_CLR(DNet_fd, &Fdexcept);
  1134. X    close(DNet_fd);
  1135. X    }
  1136. X    setenv("DNETHOST=", remotehost);
  1137. X    sprintf(sa[0].sa_data, "DNET.%s", remotehost);
  1138. X    unlink(sa[0].sa_data);
  1139. X    sa[0].sa_family = AF_UNIX;
  1140. X
  1141. X    s = socket(PF_UNIX, SOCK_STREAM, 0);
  1142. X    fcntl(s, F_SETOWN, getpid());
  1143. X    fcntl(s, F_SETFL,  FNDELAY);
  1144. X    if (bind(s, &sa[0], SASIZE(sa[0])) < 0) {
  1145. X    perror("bind");
  1146. X    exit(1);
  1147. X    }
  1148. X    if (listen(s, 5) < 0) {
  1149. X    unlink(sa[0].sa_data);
  1150. X    perror("listen");
  1151. X    exit(1);
  1152. X    }
  1153. X    DNet_fd = s;
  1154. X    Fdstate[DNet_fd] = do_localopen;
  1155. X    Fdperm[DNet_fd] = 1;
  1156. X    FD_SET(DNet_fd, &Fdread);
  1157. X    FD_SET(DNet_fd, &Fdexcept);
  1158. X}
  1159. X
  1160. SHAR_EOF
  1161. echo "extracting dnet/Makefile"
  1162. sed 's/^X//' << \SHAR_EOF > dnet/Makefile
  1163. X
  1164. X#    THE DNET DRIVER, UNIX END
  1165. X# 
  1166. X#     DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  1167. X#
  1168. X#    the BIN should be placed in your path for ease of use.  DNET uses 
  1169. X#    UNIX level sockets allowing multiple users on a system to run it
  1170. X#    independantly.  You should make a special directory (Example: .DNET)
  1171. X#    and then setenv DNETDIR ~/.DNET/  ... all clients and servers will
  1172. X#    use the enviroment variable to find/create the UNIX level sockets.
  1173. X
  1174. XBIN    = ../bin
  1175. XOBJS    = dnet.o control.o files.o globals.o net.o subs.o internal.o
  1176. X
  1177. X
  1178. X$(BIN)/dnet:    $(OBJS)
  1179. X    cc $(OBJS) -o $(BIN)/dnet
  1180. X
  1181. Xclean:    
  1182. X    rm -f *.o make.out
  1183. X
  1184. SHAR_EOF
  1185. echo "extracting dnet/MODS"
  1186. sed 's/^X//' << \SHAR_EOF > dnet/MODS
  1187. X
  1188. Xnet.c:    notion of reply expected added to NetWrite()
  1189. Xdnet.c: select modified.  On error still attempt write ops
  1190. X
  1191. SHAR_EOF
  1192. echo "extracting dnet.servers"
  1193. sed 's/^X//' << \SHAR_EOF > dnet.servers
  1194. X
  1195. X8192    ~/src/dnet.unix/bin/scopy    ~
  1196. X8193    ~/src/dnet.unix/bin/sshell    ~
  1197. X8197    ~/src/dnet.unix/bin/sloadav    ~
  1198. X8201    ~/src/dnet.unix/bin/sgcopy    ~
  1199. X
  1200. SHAR_EOF
  1201. if `test ! -d doc`
  1202. then
  1203.   mkdir doc
  1204.   echo "mkdir doc"
  1205. fi
  1206. echo "extracting doc/history"
  1207. sed 's/^X//' << \SHAR_EOF > doc/history
  1208. X
  1209. X    V1.00   sometime in 1987
  1210. X        First release
  1211. X
  1212. X    V1.20   sometime in 1988
  1213. X        Fixes to the first release
  1214. X
  1215. X    V2.00   1 March 1989
  1216. X
  1217. X        Major fixes, additions, and other items.
  1218. X
  1219. X
  1220. X
  1221. SHAR_EOF
  1222. echo "extracting doc/dnet.doc"
  1223. sed 's/^X//' << \SHAR_EOF > doc/dnet.doc
  1224. X
  1225. XUNIX/DNET
  1226. X
  1227. X    DNET [debug]
  1228. X
  1229. X    Run the DNET protocol on descriptor 0.  If the enviroment variable
  1230. X    DNETDIR exists, DNET will create the rendezvous sockets in the
  1231. X    specified directory (DNETDIR must have a hanging slash on it),
  1232. X    otherwise the current directory is used.
  1233. X
  1234. X    DNET also opens a log file (DNET.LOG) in the directory.  If the debug
  1235. X    option is given, DNET writes gobs of debugging information to the log.
  1236. X
  1237. X    Descriptor 0 may be a tty or socket.
  1238. X
  1239. X    To allow DNET to startup servers on demand, the file "dnet.servers"
  1240. X    must exist in the rendezvous directory.
  1241. X
  1242. X                    -Matt
  1243. X
  1244. SHAR_EOF
  1245. echo "extracting doc/putfiles.doc"
  1246. sed 's/^X//' << \SHAR_EOF > doc/putfiles.doc
  1247. XUNIX/PUTFILES
  1248. XAMIGA/PUTFILES
  1249. X
  1250. X    PUTFILES [-dDESTDIR] file/dir file/dir file/dir ..
  1251. X
  1252. X    File transfer client.  Transfer the specified files and or directories
  1253. X    to the destination directory on the remote machine.  For instance:
  1254. X
  1255. X    unix:  putfiles -dram: charlie.txt /usr/include
  1256. X
  1257. X    *places the file charlie.txt as ram:charlie.txt, and places the 
  1258. X     directory structure /usr/include as ram:include/(whatever).
  1259. X
  1260. X    The default destination directory depends on the remote host.  If the
  1261. X    destination is an Amiga, the default is DF0: (so you probably always
  1262. X    want to specify a -d switch).  On the UNIX end, the default is whatever
  1263. X    is set in the file dnet.servers
  1264. X
  1265. X    Currently, no file compression is done.  I also hope to add 
  1266. X    semi-automatic crash recovery (continue download where you left off
  1267. X    after a crash), though it should be noted that it is very difficult
  1268. X    to crash DNET with random modem noise.
  1269. X
  1270. SHAR_EOF
  1271. echo "extracting doc/dsoc.doc"
  1272. sed 's/^X//' << \SHAR_EOF > doc/dsoc.doc
  1273. X
  1274. X
  1275. XUNIX/DSOC
  1276. X
  1277. X
  1278. XDSOC [port#]
  1279. X
  1280. X    (default: 8196 = AMIGSHELL (CLI window))
  1281. X
  1282. X    Connect to the remote port but keep the TTY in COOKED mode (normal).
  1283. X    The connection will be terminated by killing the process on the UNIX
  1284. X    end or typing ^C.  NOTE THAT ^C KILLS DSOC AND IS NOT SENT THROUGH TO
  1285. X    THE REMOTE CLI.
  1286. X
  1287. X    The default port accesses the SCLI server on the Amiga end, which
  1288. X    starts up a CLI.  Things work properly only if *MY* PIPE: device is
  1289. X    installed on the Amiga.  Things close down properly only if you
  1290. X    have a CLI prompt when you exit DSOC.
  1291. X
  1292. X    The SCLI server currently handles only one connection at a time.
  1293. X
  1294. SHAR_EOF
  1295. echo "extracting doc/dnetlib.doc"
  1296. sed 's/^X//' << \SHAR_EOF > doc/dnetlib.doc
  1297. X
  1298. XUNIX/DNETLIB
  1299. X
  1300. X    UNIX END DNET LIBRARY INTERFACE
  1301. X
  1302. X    See the server source for good examples of usage.
  1303. X
  1304. Xlong    private;
  1305. Xuword    port
  1306. Xchar     *buf;
  1307. Xint     fd;
  1308. Xint    res1..5, bytes
  1309. Xchar    pri;
  1310. Xlong    val68, valvax;
  1311. X
  1312. Xprivate    = DListen(port)                listen on a port (server)
  1313. X     fd = DAccept(private)            accept a connection (server)
  1314. X      DNAAccept(private)            don't accept a conn.(server)
  1315. X     fd = DOpen(host, port, txpri, rxpri)    open a remote connection (client)
  1316. X   res1 = read(fd, buf, bytes)            standard unix read()
  1317. X   res2 = gread(fd, buf, bytes)            (see below)
  1318. X   res3 = ggread(fd, buf, bytes)        (see below)
  1319. X   res4 = write(fd, buf, bytes)            standard unix write()
  1320. X   res5 = gwrite(fd, buf, bytes)        (see below)
  1321. X      close(fd);
  1322. X
  1323. X   val68 = ntohl68(valvax)    convert to and from MC68000 longword format.
  1324. X   valvax= htonl68(val68)
  1325. X
  1326. X
  1327. XDListen()    sets up a UNIX domain socket in the current directory unless
  1328. X        another is specified by the DNETDIR enviroment variable.
  1329. X        Returns a private structure pointer or NULL on error.
  1330. X
  1331. X        This call will override any existing server for the port in
  1332. X        the directory permanently.  It does not cause an existing
  1333. X        server to exit, however, and you should be careful to kill
  1334. X        old servers before starting new ones.  See the source for a
  1335. X        template of correct server code.
  1336. X
  1337. XDAccept()    Accepts a new connection on the port.  Returns a file 
  1338. X        descriptor or a negative value.  This call will block.
  1339. X
  1340. XDOpen()        Attempt to connect to a port on the remote machine.  Returns
  1341. X        a file descriptor or a negative value.  The error is either
  1342. X        due to not finding DNET's master port (DNET must be running),
  1343. X        or the remote server not running.
  1344. X
  1345. X        This call looks in the current directory for the master
  1346. X        socket unless another is specified by the DNETDIR enviroment 
  1347. X        variable.
  1348. X
  1349. X        Two priorities are specified.  One for sending, and one for
  1350. X        receiving data.  A priority is a value -127 to 126 inclusive,
  1351. X        with 126 the highest priority.  Normally, priorities range
  1352. X        from -80 (file transfers) to +20 (terminal window).
  1353. X
  1354. XDEof()        Send an EOF without closing the connection.  Currently doesn't
  1355. X        work worth shit, so don't use it.
  1356. X
  1357. Xwrite()        Standard UNIX write call.  But we are dealing with a socket
  1358. X        here, so one must be careful of the return value.  (1) WRITE()
  1359. X        may not return the # bytes requested to write, but less,
  1360. X        (2) WRITE() may return a negative value indicating an error or
  1361. X        that it was interrupted or that it would have blocked (if you
  1362. X        have got non-blocking IO setup).  (3) WRITE() returns 0 on 
  1363. X        socket EOF.
  1364. X
  1365. Xgwrite()    This call will write all the bytes specified, whether the
  1366. X        socket is non-blocking or not.  It handles restarting the
  1367. X        WRITE() call on EINTR and properly handles EWOULDBLOCK.
  1368. X
  1369. X        It returns the number bytes requested or fewer on error.  If
  1370. X        fewer bytes are returned you should close the socket and exit.
  1371. X
  1372. Xread()        Standard UNIX read call.  But we are still dealing with a 
  1373. X        socket here and anything might happen.  READ() can return fewer
  1374. X        than the number of bytes requested, 0 on EOF, or a negative
  1375. X        number indicating various errors.
  1376. X
  1377. Xgread()        GREAD() handles retrying if the EINTR error occurs.  GREAD()
  1378. X        blocks until at least one character is received (or EOF), and
  1379. X        does this even if the socket is marked non-blocking.  GREAD()
  1380. X        returns 0 on EOF/ERROR.
  1381. X
  1382. Xggread()    GGREAD() not only retries on EINTR, but will block until ALL
  1383. X        the requested bytes are read in, even if the socket is marked
  1384. X        non-blocking.  GGREAD() returns -1 on EOF/ERROR.  You can also
  1385. X        tell if an EOF/ERROR occured if fewer than the requested 
  1386. X        number of bytes are read.
  1387. X
  1388. SHAR_EOF
  1389. echo "extracting doc/draw.doc"
  1390. sed 's/^X//' << \SHAR_EOF > doc/draw.doc
  1391. X
  1392. XUNIX/DRAW
  1393. X
  1394. X
  1395. XDRAW [port#]
  1396. X
  1397. X    (default: 8195 = AMIGTERM (talk window))
  1398. X
  1399. X    Connect to the remote port and place the TTY in RAW mode.  The
  1400. X    connection can only be terminated by the remote end, or by killing
  1401. X    the process on the UNIX end.
  1402. X
  1403. X    The default port brings up a 'talk' window on the Amiga.  AMIGATERM
  1404. X    will recognize a ^C sent from DRAW and close the connection.
  1405. X
  1406. SHAR_EOF
  1407. if `test ! -d lib`
  1408. then
  1409.   mkdir lib
  1410.   echo "mkdir lib"
  1411. fi
  1412. echo "extracting lib/dnetlib.h"
  1413. sed 's/^X//' << \SHAR_EOF > lib/dnetlib.h
  1414. X
  1415. X#define EFATAL 0
  1416. X#define EWARN 1
  1417. X#define EDEBUG 2
  1418. X
  1419. SHAR_EOF
  1420. echo "extracting lib/dnetlib.c"
  1421. sed 's/^X//' << \SHAR_EOF > lib/dnetlib.c
  1422. X
  1423. X/*
  1424. X *  DNETLIB.C
  1425. X *
  1426. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  1427. X *
  1428. X *  Library Interface for DNET.
  1429. X */
  1430. X
  1431. X#include <sys/types.h>
  1432. X#include <sys/socket.h>
  1433. X#include <fcntl.h>
  1434. X#include <signal.h>
  1435. X#include <stdio.h>
  1436. X#include <errno.h>
  1437. X#ifdef O_CREAT
  1438. X#include <sys/file.h>
  1439. X#endif
  1440. X#include "../lib/dnetlib.h"
  1441. X
  1442. Xextern char *getenv();
  1443. X
  1444. Xtypedef unsigned short uword;
  1445. Xtypedef unsigned long ulong;
  1446. Xtypedef unsigned char ubyte;
  1447. Xtypedef struct sockaddr SOCKADDR;
  1448. X
  1449. Xtypedef struct {
  1450. X    int s;
  1451. X    uword port;
  1452. X} CHANN;
  1453. X
  1454. X#define NAMELEN sizeof(".PORT.XXXXX")
  1455. X#define NAMEPAT "%s.PORT.%ld"
  1456. X
  1457. Xchar *getdirpart();
  1458. X
  1459. XCHANN *
  1460. XDListen(port)
  1461. Xuword port;
  1462. X{
  1463. X    CHANN *chan;
  1464. X    int s;
  1465. X    SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
  1466. X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  1467. X
  1468. X    sprintf(sa->sa_data, NAMEPAT, dirstr, port);
  1469. X    sa->sa_family = AF_UNIX;
  1470. X    unlink(sa->sa_data);
  1471. X
  1472. X    s = socket(PF_UNIX, SOCK_STREAM, 0);
  1473. X    fcntl(s, F_SETOWN, getpid());
  1474. X    if (bind(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+strlen(sa->sa_data)) < 0) {
  1475. X    close(s);
  1476. X    free(sa);
  1477. X    return(NULL);
  1478. X    }
  1479. X    if (listen(s, 5) < 0) {
  1480. X    close(s);
  1481. X    unlink(sa->sa_data);
  1482. X    free(sa);
  1483. X    return(NULL);
  1484. X    }
  1485. X    chan = (CHANN *)malloc(sizeof(CHANN));
  1486. X    chan->s = s;
  1487. X    chan->port = port;
  1488. X    free(sa);
  1489. X    return(chan);
  1490. X}
  1491. X
  1492. X
  1493. XDUnListen(chan)
  1494. XCHANN *chan;
  1495. X{
  1496. X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  1497. X    char buf[32];
  1498. X
  1499. X    close(chan->s);
  1500. X    sprintf(buf, NAMEPAT, dirstr, chan->port);
  1501. X    unlink(buf);
  1502. X    free(chan);
  1503. X}
  1504. X
  1505. XDAccept(chan)
  1506. XCHANN *chan;
  1507. X{
  1508. X    SOCKADDR sa;
  1509. X    int addrlen = sizeof(sa);
  1510. X    int fd;
  1511. X
  1512. X    fd = accept(chan->s, &sa, &addrlen);
  1513. X    return(fd);
  1514. X}
  1515. X
  1516. XDOpen(host, port, txpri, rxpri)
  1517. Xchar *host;
  1518. Xuword port;
  1519. Xchar txpri, rxpri;
  1520. X{
  1521. X    int s;
  1522. X    char rc;
  1523. X    short xb[3];
  1524. X    SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
  1525. X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  1526. X
  1527. X    if (rxpri < -127)
  1528. X    rxpri = -127;
  1529. X    if (rxpri > 126)
  1530. X    rxpri = 126;
  1531. X    if (txpri < -127)
  1532. X    txpri = -127;
  1533. X    if (txpri > 126)
  1534. X    txpri = 126;
  1535. X
  1536. X    if (host == NULL)
  1537. X    host = (getenv("DNETHOST")) ? getenv("DNETHOST"):"";
  1538. X
  1539. X    sa->sa_family = AF_INET;
  1540. X    sprintf(sa->sa_data, "%s%s%s", dirstr, "DNET.", host);
  1541. X
  1542. X    s = socket(PF_UNIX, SOCK_STREAM, 0);
  1543. X    fcntl(s, F_SETOWN, getpid());
  1544. X    if (connect(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+
  1545. X    strlen(sa->sa_data))<0) {
  1546. X    close(s);
  1547. X    free(sa);
  1548. X    return(-1);
  1549. X    }
  1550. X    free(sa);
  1551. X    xb[0] = port;
  1552. X    ((char *)&xb[1])[0] = txpri;
  1553. X    ((char *)&xb[1])[1] = rxpri;
  1554. X    write(s, xb, 4);
  1555. X    if (read(s, &rc, 1) == 1 && rc == 0)
  1556. X    return(s);
  1557. X    close(s);
  1558. X    return(-1);
  1559. X}
  1560. X
  1561. XDEof(fd)
  1562. X{
  1563. X    char dummy;
  1564. X
  1565. X    shutdown(fd, 1);
  1566. X    write(fd, &dummy, 0);
  1567. X}
  1568. X
  1569. Xgwrite(fd, buf, bytes)
  1570. Xchar *buf;
  1571. X{
  1572. X    int n;
  1573. X    int orig = bytes;
  1574. X    extern int errno;
  1575. X    while (bytes) {
  1576. X    n = write(fd, buf, bytes);
  1577. X    if (n > 0) {
  1578. X        bytes -= n;
  1579. X        buf += n;
  1580. X        continue;
  1581. X    }
  1582. X    if (n < 0) {
  1583. X        if (errno == EINTR)
  1584. X        continue;
  1585. X        if (errno == EWOULDBLOCK) {
  1586. X        int wm = 1 << fd;
  1587. X        int em = 1 << fd;
  1588. X        if (select(fd+1, NULL, &wm, &em, NULL) < 0)
  1589. X            continue;
  1590. X        if (wm)
  1591. X            continue;
  1592. X        }
  1593. X        return(orig - bytes);
  1594. X    }
  1595. X    }
  1596. X    return(orig);
  1597. X}
  1598. X
  1599. Xgread(fd, buf, bytes)
  1600. Xchar *buf;
  1601. X{
  1602. X    int n;
  1603. X    int orig = bytes;
  1604. X    extern int errno;
  1605. X    while (bytes) {
  1606. X    n = read(fd, buf, bytes);
  1607. X    if (n > 0) {
  1608. X        bytes -= n;
  1609. X        buf += n;
  1610. X        break;
  1611. X    }
  1612. X    if (n < 0) {
  1613. X        if (errno == EINTR)
  1614. X        continue;
  1615. X        if (errno == EWOULDBLOCK) {
  1616. X        int rm = 1 << fd;
  1617. X        int em = 1 << fd;
  1618. X        if (select(fd+1, &rm, NULL, &em, NULL) < 0)
  1619. X            continue;
  1620. X        if (rm)
  1621. X            continue;
  1622. X        }
  1623. X        return(orig - bytes);
  1624. X    }
  1625. X    if (n == 0)
  1626. X        break;
  1627. X    }
  1628. X    return(orig - bytes);
  1629. X}
  1630. X
  1631. Xggread(fd, buf, bytes)
  1632. Xchar *buf;
  1633. X{
  1634. X    int n;
  1635. X    int ttl = 0;
  1636. X    while (bytes) {
  1637. X    n = gread(fd, buf, bytes);
  1638. X    if (n > 0) {
  1639. X        bytes -= n;
  1640. X        buf += n;
  1641. X        ttl += n;
  1642. X        continue;
  1643. X    }
  1644. X    return(-1);
  1645. X    }
  1646. X    return(ttl);
  1647. X}
  1648. X
  1649. X/*
  1650. X *    Convert to and from 68000 longword format.  Of course, it really
  1651. X *    doesn't matter what format you use, just as long as it is defined.
  1652. X */
  1653. X
  1654. Xntohl68(n)
  1655. Xulong n;
  1656. X{
  1657. X    return(
  1658. X    (((ubyte *)&n)[0] << 24)|
  1659. X    (((ubyte *)&n)[1] << 16)|
  1660. X    (((ubyte *)&n)[2] << 8)|
  1661. X    (((ubyte *)&n)[3])
  1662. X    );
  1663. X}
  1664. X
  1665. Xhtonl68(n)
  1666. Xulong n;
  1667. X{
  1668. X    ulong v;
  1669. X    ((ubyte *)&v)[0] = n >> 24;
  1670. X    ((ubyte *)&v)[1] = n >> 16;
  1671. X    ((ubyte *)&v)[2] = n >> 8;
  1672. X    ((ubyte *)&v)[3] = n;
  1673. X    return(v);
  1674. X}
  1675. X
  1676. X
  1677. XDoOption(ac, av, ops, args)
  1678. Xshort ac;
  1679. Xchar *av[];
  1680. Xchar *ops;
  1681. Xlong args;
  1682. X{
  1683. X    register short i;
  1684. X    short j;
  1685. X
  1686. X    for (i = j = 1; i < ac; ++i) {
  1687. X    register char *ptr = av[i];
  1688. X    if (*ptr != '-') {
  1689. X        av[j++] = av[i];
  1690. X        continue;
  1691. X    }
  1692. X    while (*++ptr) {
  1693. X        register char *op;
  1694. X        long **ap = (long **)&args;
  1695. X        short isshort;
  1696. X
  1697. X        for (op = ops; *op && *op != *ptr;) {
  1698. X        if (*op == *ptr)
  1699. X            break;
  1700. X        if (*++op == '%') {
  1701. X            while (*op && *op != 's' && *op != 'd')
  1702. X            ++op;
  1703. X            if (*op)
  1704. X            ++op;
  1705. X        }
  1706. X        if (*op == ',')     /*  optional ,  */
  1707. X            ++op;
  1708. X        ++ap;
  1709. X        }
  1710. X        if (*op == 0)
  1711. X        return(-1);
  1712. X        if (op[1] != '%') {
  1713. X        *(short *)*ap = 1;
  1714. X        ++ap;
  1715. X        continue;
  1716. X        }
  1717. X        op += 2;
  1718. X        isshort = 1;
  1719. X        while (*op && *op != 's' && *op != 'd') {
  1720. X        switch(*op) {
  1721. X        case 'h':
  1722. X            isshort = 1;
  1723. X            break;
  1724. X        case 'l':
  1725. X            isshort = 0;
  1726. X            break;
  1727. X        default:
  1728. X            return(-1);
  1729. X        }
  1730. X        ++op;
  1731. X        }
  1732. X        switch(*op) {
  1733. X        case 's':
  1734. X        if (ptr[1]) {
  1735. X            *(char **)*ap = ptr + 1;
  1736. X            ptr = "\0";
  1737. X        } else {
  1738. X            *(char **)*ap = av[++i];
  1739. X        }
  1740. X        break;
  1741. X        case 'd':
  1742. X        if (isshort)
  1743. X            *(short *)*ap = atoi(++ptr);
  1744. X        else
  1745. X            *(long *)*ap = atoi(++ptr);
  1746. X        while (*ptr >= '0' && *ptr <= '9')
  1747. X            ++ptr;
  1748. X        break;
  1749. X        default:
  1750. X        return(-1);
  1751. X        }
  1752. X    }
  1753. X    }
  1754. X    return(j);
  1755. X}
  1756. X
  1757. Xelog(how, ctl, arg)
  1758. Xchar *ctl;
  1759. Xlong arg;
  1760. X{
  1761. X    char *dir = getenv("DNETDIR");
  1762. X    FILE *fi;
  1763. X    char buf[256];
  1764. X    long dtime;
  1765. X
  1766. X    time(&dtime);
  1767. X
  1768. X    if (!dir)
  1769. X    dir = "";
  1770. X    sprintf(buf, "%s%s", dir, "DNET.LOG");
  1771. X    if (fi = fopen(buf, "a")) {
  1772. X    strcpy(buf, ctime(&dtime));
  1773. X    buf[strlen(buf)-1] = 0;
  1774. X    fprintf(fi, "%s ", buf);
  1775. X    fprintf(fi, ctl, arg);
  1776. X    putc('\n', fi);
  1777. X    fclose(fi);
  1778. X    }
  1779. X    if (how == EFATAL)
  1780. X    exit(1);
  1781. X}
  1782. X
  1783. SHAR_EOF
  1784. echo "extracting lib/Makefile"
  1785. sed 's/^X//' << \SHAR_EOF > lib/Makefile
  1786. X
  1787. X
  1788. Xdnetlib.o : dnetlib.c
  1789. X    cc -c dnetlib.c
  1790. X
  1791. SHAR_EOF
  1792. if `test ! -d server`
  1793. then
  1794.   mkdir server
  1795.   echo "mkdir server"
  1796. fi
  1797. echo "extracting server/sgcopy.c"
  1798. sed 's/^X//' << \SHAR_EOF > server/sgcopy.c
  1799. X
  1800. X/*
  1801. X *  SGCOPY.C     V1.1
  1802. X *
  1803. X *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  1804. X *
  1805. X *  GET-COPY SERVER    (NEW COPY SERVER)
  1806. X *
  1807. X *  The current version only accepts one connection at a time.    This server
  1808. X *  will send requested files to the remote machine.
  1809. X *
  1810. X *  length in 68000 longword format.
  1811. X */
  1812. X
  1813. X#include <sys/types.h>
  1814. X#include <sys/stat.h>
  1815. X#include <sys/wait.h>
  1816. X#include <sys/time.h>
  1817. X#include <sys/dir.h>
  1818. X#include <sys/file.h>
  1819. X#include <sys/resource.h>
  1820. X#include <stdio.h>
  1821. X#include <errno.h>
  1822. X#include <signal.h>
  1823. X
  1824. X#include "servers.h"
  1825. X
  1826. Xtypedef struct {
  1827. X    char    Cmd;
  1828. X    char    Str[64];
  1829. X    long    Val;
  1830. X} HDR;
  1831. X
  1832. Xtypedef unsigned char ubyte;
  1833. Xchar *getnamepart();
  1834. Xchar *getdirpart();
  1835. X
  1836. Xchar Buf[4096];
  1837. Xint Chan;
  1838. X
  1839. Xchandler()
  1840. X{
  1841. X    union wait stat;
  1842. X    struct rusage rus;
  1843. X    while (wait3(&stat, WNOHANG, &rus) > 0);
  1844. X}
  1845. X
  1846. Xmain(ac,av)
  1847. Xchar *av[];
  1848. X{
  1849. X    long chann = DListen(PORT_GFILECOPY);
  1850. X    int fd;
  1851. X    int n;
  1852. X    char buf[256];
  1853. X    extern int errno;
  1854. X
  1855. X    if (av[1])
  1856. X    chdir(av[1]);
  1857. X    signal(SIGCHLD, chandler);
  1858. X    signal(SIGPIPE, SIG_IGN);
  1859. X    for (;;) {
  1860. X    fd = DAccept(chann);
  1861. X    if (fd < 0) {
  1862. X        if (errno == EINTR)
  1863. X        continue;
  1864. X        break;
  1865. X    }
  1866. X    if (fork() == NULL) {
  1867. X        SGCopy(fd);
  1868. X        _exit(1);
  1869. X    }
  1870. X    close(fd);
  1871. X    }
  1872. X    perror("SCOPY");
  1873. X}
  1874. X
  1875. XSGCopy(fd)
  1876. Xint fd;
  1877. X{
  1878. X    short error = 0;
  1879. X    static HDR Hdr;
  1880. X
  1881. X    Chan = fd;
  1882. X    error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
  1883. X    if (error)
  1884. X    return(error);
  1885. X    switch(ReadHeader(&Hdr)) {
  1886. X    default:
  1887. X    case -1:
  1888. X    error = 1;
  1889. X    return(error);
  1890. X    case 'H':
  1891. X    break;
  1892. X    }
  1893. X    while (!error) {
  1894. X    switch(ReadHeader(&Hdr)) {
  1895. X    case 'G':
  1896. X        {
  1897. X        char svdir[1024];
  1898. X        getwd(svdir);
  1899. X        if (chdir(getdirpart(Hdr.Str)) < 0) {
  1900. X            error = WriteHeader('N', "Unable to cd to dir", 0);
  1901. X        } else {
  1902. X                error = PutObject(getnamepart(Hdr.Str));
  1903. X        }
  1904. X        chdir(svdir);
  1905. X        }
  1906. X        break;
  1907. X    case 'E':
  1908. X        goto done;
  1909. X    case 'P':   /*  put-files, not implemented  */
  1910. X    default:
  1911. X        error = 1;
  1912. X        break;
  1913. X    }
  1914. X    }
  1915. Xdone:
  1916. X    ;
  1917. X}
  1918. X
  1919. XPutObject(str)
  1920. Xchar *str;
  1921. X{
  1922. X    struct stat stat;
  1923. X    short error = 0;
  1924. X
  1925. X    if (lstat(str, &stat) < 0) {
  1926. X    error = WriteHeader('N', "Unable to find object", 0);
  1927. X    return(0);
  1928. X    }
  1929. X    if (stat.st_mode & S_IFDIR) {
  1930. X    error = PutDir(str);
  1931. X    } else {
  1932. X    error = PutFile(str);
  1933. X    }
  1934. X    return(0);
  1935. X}
  1936. X
  1937. XPutDir(name)
  1938. Xchar *name;
  1939. X{
  1940. X    struct stat stat;
  1941. X    char svdir[1024];
  1942. X    static HDR Hdr;
  1943. X    short error = 0;
  1944. X    char *fn = getnamepart(name);
  1945. X    DIR *dir;
  1946. X    struct direct *de;
  1947. X
  1948. X    if (lstat(name, &stat) < 0 || !(dir = opendir(name))) {
  1949. X    WriteHeader('N', "Possible Disk Error", 0);
  1950. X    error = 1;
  1951. X    goto done;
  1952. X    }
  1953. X    if (error = WriteHeader('D', fn, 0)) 
  1954. X    goto done;
  1955. X    switch(ReadHeader(&Hdr)) {
  1956. X    case 'Y':
  1957. X    break;
  1958. X    case 'S':
  1959. X    goto done;
  1960. X    case 'N':
  1961. X    error = 1;
  1962. X    break;
  1963. X    default:
  1964. X    error = 1;
  1965. X    break;
  1966. X    }
  1967. X    if (error)
  1968. X    goto done;
  1969. X
  1970. X    getwd(svdir);
  1971. X    if (chdir(name) < 0) {
  1972. X    error = 1;
  1973. X    WriteHeader('N', "unable to chdir", 0);
  1974. X    }
  1975. X    if (error)
  1976. X    goto done;
  1977. X
  1978. X    while (de = readdir(dir)) {
  1979. X    if (strcmp(de->d_name, ".") == 0)
  1980. X        continue;
  1981. X    if (strcmp(de->d_name, "..") == 0)
  1982. X        continue;
  1983. X    if (lstat(de->d_name, &stat) < 0) {
  1984. X        continue;
  1985. X    }
  1986. X    if (stat.st_mode & S_IFDIR) {
  1987. X        error = PutDir(de->d_name);
  1988. X    } else {
  1989. X        error = PutFile(de->d_name);
  1990. X    }
  1991. X    if (error)
  1992. X        break;
  1993. X    }
  1994. X    WriteHeader('E', NULL, 0);
  1995. X    chdir(svdir);
  1996. Xdone:
  1997. X    return(error);
  1998. X}
  1999. X
  2000. XPutFile(name)
  2001. Xchar *name;
  2002. X{
  2003. X    int fd = -1;
  2004. X    static HDR Hdr;
  2005. X    long len;
  2006. X    short error = 0;
  2007. X    char *fn = getnamepart(name);
  2008. X
  2009. X    fd = open(fn, O_RDONLY, 0);
  2010. X    if (fd < 0) {       /*  don't do anything if unable to open it */
  2011. X    WriteHeader('N', "file not readable", 0);
  2012. X    goto done;
  2013. X    }
  2014. X    len = lseek(fd, 0L, 2);
  2015. X    if (error = WriteHeader('F', fn, len))
  2016. X    goto done;
  2017. X    switch(ReadHeader(&Hdr)) {
  2018. X    case 'Y':
  2019. X    lseek(fd, Hdr.Val, 0);  /*  start pos.  */
  2020. X    len -= Hdr.Val;
  2021. X    if (len < 0)
  2022. X        len = 0;
  2023. X    break;
  2024. X    case 'S':
  2025. X    goto done;
  2026. X    case 'N':
  2027. X    error = 1;
  2028. X    break;
  2029. X    default:
  2030. X    error = 1;
  2031. X    break;
  2032. X    }
  2033. X    if (error)
  2034. X    goto done;
  2035. X    while (len) {
  2036. X    register long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
  2037. X
  2038. X    if (read(fd, Buf, n) != n) {    /*  read failed! */
  2039. X        error = 10;
  2040. X        goto done;
  2041. X    }
  2042. X    if (gwrite(Chan, Buf, n) != n) {
  2043. X        error = 10;
  2044. X        goto done;
  2045. X    }
  2046. X    len -= n;
  2047. X    }
  2048. Xdone:
  2049. X    if (fd >= 0)
  2050. X    close(fd);
  2051. X    return(error);
  2052. X}
  2053. X
  2054. X
  2055. XWriteHeader(c, str, len)
  2056. Xchar c;
  2057. Xchar *str;
  2058. Xlong len;
  2059. X{
  2060. X    ubyte sl;
  2061. X
  2062. X    if (str == NULL)
  2063. X    str = "";
  2064. X    sl = strlen(str);
  2065. X
  2066. X    if (gwrite(Chan, &c, 1) < 0)
  2067. X    return(1);
  2068. X    if (gwrite(Chan, &sl,1) < 0)
  2069. X    return(1);
  2070. X    if (gwrite(Chan, str, sl) != sl)
  2071. X    return(1);
  2072. X    len = htonl68(len);
  2073. X    if (gwrite(Chan, &len, 4) != 4)
  2074. X    return(1);
  2075. X    return(0);
  2076. X}
  2077. X
  2078. XReadHeader(hdr)
  2079. XHDR *hdr;
  2080. X{
  2081. X    ubyte sl;
  2082. X    ubyte cmd;
  2083. X
  2084. X    hdr->Cmd = -1;
  2085. X    if (ggread(Chan, &cmd, 1) != 1)
  2086. X    return(-1);
  2087. X    if (ggread(Chan, &sl, 1) != 1)
  2088. X    return(-1);
  2089. X    if (sl >= sizeof(hdr->Str)) {
  2090. X    return(-1);
  2091. X    }
  2092. X    if (ggread(Chan, hdr->Str, sl) != sl)
  2093. X    return(-1);
  2094. X    hdr->Str[sl] = 0;
  2095. X    if (ggread(Chan, &hdr->Val, 4) != 4)
  2096. X    return(-1);
  2097. X    hdr->Val = ntohl68(hdr->Val);
  2098. X    hdr->Cmd = cmd;
  2099. X    return(hdr->Cmd);
  2100. X}
  2101. X
  2102. Xchar *
  2103. Xgetnamepart(str)
  2104. Xchar *str;
  2105. X{
  2106. X    register char *ptr = str + strlen(str);
  2107. X
  2108. X    while (ptr >= str) {
  2109. X    if (*ptr == '/')
  2110. X        break;
  2111. X    --ptr;
  2112. X    }
  2113. X    return(ptr+1);
  2114. X}
  2115. X
  2116. Xchar *
  2117. Xgetdirpart(str)
  2118. Xchar *str;
  2119. X{
  2120. X    static char buf[1024];
  2121. X
  2122. X    strcpy(buf, str);
  2123. X    getnamepart(buf)[0] = 0;
  2124. X    if (buf[0] == 0)
  2125. X    return(".");
  2126. X    return(buf);
  2127. X}
  2128. SHAR_EOF
  2129. echo "extracting server/sshell.c"
  2130. sed 's/^X//' << \SHAR_EOF > server/sshell.c
  2131. X
  2132. X/*
  2133. X *  S_SHELL.C        OBSOLETE OBSOLETE OBSOLETE
  2134. X *
  2135. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  2136. X *
  2137. X *   Connect a csh to a pseudo terminal pair... PORT_ALPHATERM
  2138. X *   NOTE!!  PORT_IALPHATERM (a pseudo-terminal csh) is also available
  2139. X *   through the FTERM client program on the Amiga side, and much faster
  2140. X *   since the server for PORT_IALPHATERM is DNET itself (one less process
  2141. X *   to go through).
  2142. X *
  2143. X *    -doesn't handle SIGWINCH
  2144. X *    -doesn't handle flow control ... don't cat any long files!
  2145. X */
  2146. X
  2147. X#include <stdio.h>
  2148. X#include <sys/wait.h>
  2149. X#include <sys/time.h>
  2150. X#include <sys/resource.h>
  2151. X#include <errno.h>
  2152. X#include <signal.h>
  2153. X
  2154. X#include "servers.h"
  2155. X
  2156. Xchandler()
  2157. X{
  2158. X    union wait stat;
  2159. X    struct rusage rus;
  2160. X    while (wait3(&stat, WNOHANG, &rus) > 0);
  2161. X}
  2162. X
  2163. Xmain(ac,av)
  2164. Xchar *av[];
  2165. X{
  2166. X    long chann = DListen(PORT_ALPHATERM);
  2167. X    int fd;
  2168. X    int n;
  2169. X    char buf[256];
  2170. X    extern int errno;
  2171. X
  2172. X    if (av[1])
  2173. X    chdir(av[1]);
  2174. X    signal(SIGCHLD, chandler);
  2175. X    signal(SIGPIPE, SIG_IGN);
  2176. X    for (;;) {
  2177. X    fd = DAccept(chann);
  2178. X    if (fd < 0) {
  2179. X        if (errno == EINTR)
  2180. X        continue;
  2181. X        break;
  2182. X    }
  2183. X    if (fork() == NULL) {
  2184. X        dup2(fd, 0);
  2185. X        dup2(fd, 1);
  2186. X        dup2(fd, 2);
  2187. X        close(fd);
  2188. X        execl("/usr/ucb/rlogin", "rlogin", "localhost", NULL);
  2189. X        exit(1);
  2190. X    }
  2191. X    close(fd);
  2192. X    }
  2193. X    perror("SSHELL");
  2194. X}
  2195. X
  2196. SHAR_EOF
  2197. echo "extracting server/sloadav.c"
  2198. sed 's/^X//' << \SHAR_EOF > server/sloadav.c
  2199. X
  2200. X/*
  2201. X *    SLOADAV.C
  2202. X *
  2203. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  2204. X *
  2205. X *    Reports the load average every 5 minutes or until the connection
  2206. X *    is closed.
  2207. X */
  2208. X
  2209. X#include <stdio.h>
  2210. X#include <sys/wait.h>
  2211. X#include <sys/time.h>
  2212. X#include <sys/resource.h>
  2213. X#include <errno.h>
  2214. X#include <signal.h>
  2215. X
  2216. X#include "servers.h"
  2217. X
  2218. Xchandler()
  2219. X{
  2220. X    union wait stat;
  2221. X    struct rusage rus;
  2222. X    while (wait3(&stat, WNOHANG, &rus) > 0);
  2223. X}
  2224. X
  2225. Xmain(ac,av)
  2226. Xchar *av[];
  2227. X{
  2228. X    long chann = DListen(PORT_LOADAV);
  2229. X    int fd;
  2230. X    int n;
  2231. X    char buf[256];
  2232. X    extern int errno;
  2233. X
  2234. X    if (av[1])
  2235. X    chdir(av[1]);
  2236. X    signal(SIGCHLD, chandler);
  2237. X    signal(SIGPIPE, SIG_IGN);
  2238. X    for (;;) {
  2239. X    fd = DAccept(chann);
  2240. X    if (fd < 0) {
  2241. X        if (errno == EINTR)
  2242. X        continue;
  2243. X        break;
  2244. X    }
  2245. X    if (fork() == NULL) {
  2246. X        do_loadav(fd);
  2247. X        close(fd);
  2248. X        _exit(1);
  2249. X    }
  2250. X    close(fd);
  2251. X    }
  2252. X    perror("SLOADAV");
  2253. X}
  2254. X
  2255. Xdo_loadav(fd)
  2256. X{
  2257. X    char dummy;
  2258. X    char buf[256];
  2259. X    FILE *fi;
  2260. X
  2261. X    while (ggread(fd, &dummy, 1) == 1) {
  2262. X    fi = popen("uptime", "r");
  2263. X    if (fi == NULL)
  2264. X        break;
  2265. X    if (fgets(buf, 256, fi)) {
  2266. X        dummy = strlen(buf);
  2267. X        buf[dummy-1] = 0;
  2268. X        gwrite(fd, &dummy, 1);
  2269. X        gwrite(fd, buf, dummy);
  2270. X    }
  2271. X    if (ferror(fi))
  2272. X        break;
  2273. X    pclose(fi);
  2274. X    }
  2275. X}
  2276. X
  2277. SHAR_EOF
  2278. echo "extracting server/scopy.c"
  2279. sed 's/^X//' << \SHAR_EOF > server/scopy.c
  2280. X
  2281. X/*
  2282. X *    SCOPY.C
  2283. X *
  2284. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  2285. X *
  2286. X *    Remote file copy server (putfiles is the client program)
  2287. X */
  2288. X
  2289. X#include <sys/types.h>
  2290. X#include <sys/stat.h>
  2291. X#include <sys/wait.h>
  2292. X#include <sys/time.h>
  2293. X#include <sys/file.h>
  2294. X#include <sys/resource.h>
  2295. X#include <stdio.h>
  2296. X#include <errno.h>
  2297. X#include <signal.h>
  2298. X
  2299. X#include "servers.h"
  2300. X#include "../lib/dnetlib.h"
  2301. X
  2302. Xchar Buf[4096];
  2303. X
  2304. Xchandler()
  2305. X{
  2306. X    union wait stat;
  2307. X    struct rusage rus;
  2308. X    while (wait3(&stat, WNOHANG, &rus) > 0);
  2309. X}
  2310. X
  2311. Xmain(ac,av)
  2312. Xchar *av[];
  2313. X{
  2314. X    long chann = DListen(PORT_FILECOPY);
  2315. X    int fd;
  2316. X    int n;
  2317. X    char buf[256];
  2318. X    extern int errno;
  2319. X
  2320. X    elog(EDEBUG, "SCOPY START", 0);
  2321. X    if (av[1])
  2322. X        chdir(av[1]);
  2323. X    signal(SIGCHLD, chandler);
  2324. X    signal(SIGPIPE, SIG_IGN);
  2325. X    for (;;) {
  2326. X    fd = DAccept(chann);
  2327. X    if (fd < 0) {
  2328. X        if (errno == EINTR)
  2329. X        continue;
  2330. X        break;
  2331. X    }
  2332. X        elog(EDEBUG, "SCOPY CONNECT", 0);
  2333. X    if (fork() == NULL) {
  2334. X        putdir(fd, "."); 
  2335. X        _exit(1);
  2336. X    }
  2337. X    close(fd);
  2338. X    }
  2339. X    perror("SCOPY");
  2340. X}
  2341. X
  2342. Xputdir(chan, dirname)
  2343. Xchar *dirname;
  2344. X{
  2345. X    struct stat stat;
  2346. X    char olddir[256];
  2347. X    char co, nl, name[128];
  2348. X    long len;
  2349. X    int ret = -1;
  2350. X
  2351. X    getwd(olddir);
  2352. X    if (lstat(dirname, &stat) >= 0 && !(stat.st_mode & S_IFDIR)) {
  2353. X    char rc = 'N';
  2354. X    gwrite(chan, &rc, 1);
  2355. X    elog(EWARN, "SCOPY: Unable to cd to dir '%s'", dirname);
  2356. X    return(1);
  2357. X    }
  2358. X    if (chdir(dirname) < 0) {
  2359. X    if (mkdir(dirname, 0777) < 0 || chdir(dirname) < 0) {
  2360. X        char rc = 'N';
  2361. X        elog(EWARN, "SCOPY: Unable to create directory '%s'", dirname);
  2362. X        gwrite(chan, &rc, 1);
  2363. X        return(1);
  2364. X    }
  2365. X    }
  2366. X    co = 'Y';
  2367. X    gwrite(chan, &co, 1);
  2368. X    while (ggread(chan, &co, 1) == 1) {
  2369. X    if (ggread(chan, &nl, 1) != 1 || ggread(chan, name, nl) != nl)
  2370. X        break;
  2371. X    if (ggread(chan, &len, 4) != 4)
  2372. X        break;
  2373. X    len = ntohl68(len);
  2374. X    switch(co) {
  2375. X    case 'C':
  2376. X        co = 'Y';
  2377. X            if (chdir(name) < 0) {
  2378. X        if (mkdir(name, 0777) < 0 || chdir(name) < 0)  {
  2379. X            co = 'N';
  2380. X                elog(EWARN, "SCOPY: Unable to create directory '%s'", 
  2381. X            dirname);
  2382. X        }
  2383. X        }
  2384. X        gwrite(chan, &co, 1);
  2385. X        break;
  2386. X    case 'W':
  2387. X        if (putfile(chan, name, len) < 0) {
  2388. X        ret = -1;
  2389. X        elog(EWARN, "SCOPY: Failure on file %.*s", len, name);
  2390. X        goto fail;
  2391. X        }
  2392. X        break;
  2393. X    case 'X':
  2394. X        if (putdir(chan, name) < 0) {
  2395. X        ret = -1;
  2396. X        goto fail;
  2397. X        }
  2398. X        break;
  2399. X    case 'Y':
  2400. X        ret = 1;
  2401. X        co = 'Y';
  2402. X        gwrite(chan, &co, 1);
  2403. X        goto fail;
  2404. X    default:
  2405. X        co = 'N';
  2406. X        gwrite(chan, &co, 1);
  2407. X        break;
  2408. X    }
  2409. X    }
  2410. Xfail:
  2411. X    chdir(olddir);
  2412. X    return(ret);
  2413. X}
  2414. X
  2415. Xputfile(chan, name, len)
  2416. Xchar *name;
  2417. X{
  2418. X    long fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  2419. X    long n, r;
  2420. X    char rc;
  2421. X
  2422. X    if (fd < 0) {
  2423. X    rc = 'N';
  2424. X    gwrite(chan, &rc, 1);
  2425. X    return(0);
  2426. X    }
  2427. X    rc = 'Y';
  2428. X    gwrite(chan, &rc, 1);
  2429. X    while (len) {
  2430. X    r = (len > sizeof(Buf)) ? sizeof(Buf) : len;
  2431. X    n = ggread(chan, Buf, r);
  2432. X    if (n != r)
  2433. X        break;
  2434. X        if (write(fd, Buf, n) != n)
  2435. X        break;
  2436. X    len -= n;
  2437. X    }
  2438. X    close(fd);
  2439. X    if (len) {
  2440. X    unlink(name);
  2441. X    return(-1);
  2442. X    }
  2443. X    rc = 'Y';
  2444. X    gwrite(chan, &rc, 1);
  2445. X    return(0);
  2446. X}
  2447. X
  2448. SHAR_EOF
  2449. echo "extracting server/Makefile"
  2450. sed 's/^X//' << \SHAR_EOF > server/Makefile
  2451. X
  2452. X#    DNET SERVERS
  2453. X#
  2454. X#
  2455. X#    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  2456. X
  2457. XNETLIB = ../lib/dnetlib.o
  2458. XBIN = ../bin
  2459. X
  2460. X
  2461. Xall:    $(NETLIB) $(BIN)/scopy $(BIN)/sshell \
  2462. X    $(BIN)/sloadav $(BIN)/sgcopy
  2463. X
  2464. X$(BIN)/scopy:        scopy.o
  2465. X    cc scopy.o $(NETLIB) -o $(BIN)/scopy
  2466. X
  2467. X$(BIN)/sgcopy:        sgcopy.o
  2468. X    cc sgcopy.o $(NETLIB) -o $(BIN)/sgcopy
  2469. X
  2470. X$(BIN)/sshell:        sshell.o
  2471. X    cc sshell.o $(NETLIB) -o $(BIN)/sshell
  2472. X
  2473. X$(BIN)/sloadav:        sloadav.o
  2474. X    cc sloadav.o $(NETLIB) -o $(BIN)/sloadav
  2475. X
  2476. Xclean:
  2477. X    rm -f *.o make.out
  2478. X
  2479. SHAR_EOF
  2480. echo "extracting server/servers.h"
  2481. sed 's/^X//' << \SHAR_EOF > server/servers.h
  2482. X
  2483. X/*
  2484. X *  SERVERS.H
  2485. X *
  2486. X *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  2487. X */
  2488. X
  2489. X#define PORT_FILECOPY    8192
  2490. X#define PORT_ALPHATERM    8193
  2491. X#define PORT_ECHO    8194
  2492. X#define PORT_IALPHATERM 8195
  2493. X#define PORT_AMIGATERM    8195
  2494. X#define PORT_AMIGASHELL 8196
  2495. X#define PORT_LOADAV    8197
  2496. X#define PORT_PRINTER    8198
  2497. X#define PORT_PASSWD    8199
  2498. X#define PORT_BBS    8200
  2499. X#define PORT_GFILECOPY    8201
  2500. X
  2501. X
  2502. SHAR_EOF
  2503. echo "End of archive 2 (of 2)"
  2504. # if you want to concatenate archives, remove anything after this line
  2505. exit
  2506.